\subsubsection{\OptimizingXcodeIV (\ThumbTwoMode)}

Par défaut Xcode 4.6.3 génère du code pour Thumb-2 de cette manière:

\begin{lstlisting}[caption=\OptimizingXcodeIV (\ThumbTwoMode),style=customasmARM]
__text:00002B6C                   _hello_world
__text:00002B6C 80 B5          PUSH            {R7,LR}
__text:00002B6E 41 F2 D8 30    MOVW            R0, #0x13D8
__text:00002B72 6F 46          MOV             R7, SP
__text:00002B74 C0 F2 00 00    MOVT.W          R0, #0
__text:00002B78 78 44          ADD             R0, PC
__text:00002B7A 01 F0 38 EA    BLX             _puts
__text:00002B7E 00 20          MOVS            R0, #0
__text:00002B80 80 BD          POP             {R7,PC}

...

__cstring:00003E70 48 65 6C 6C 6F 20+aHelloWorld  DCB "Hello world!",0xA,0
\end{lstlisting}

% Q: If you subtract 0x13D8 from 0x3E70,
% you actually get a location that is not in this function, or in _puts.
% How is PC-relative addressing done in THUMB2?
% A: it's not Thumb-related. there are just mess with two different segments. TODO: rework this listing.

\myindex{\ThumbTwoMode}
\myindex{ARM!\Instructions!BL}
\myindex{ARM!\Instructions!BLX}

Les instructions \TT{BL} et \TT{BLX} en mode Thumb, comme on s'en souviens, sont
encodées comme une paire d'instructions 16 bits.
En Thumb-2 ces opcodes \IT{substituts} sont étendus de telle sorte que les nouvelles
instructions puissent être encodées comme des instructions 32-bit.

C'est évident en considérant que les opcodes des instructions Thumb-2 commencent
toujours avec \TT{0xFx} ou \TT{0xEx}.

Mais dans le listing d'\IDA les octets d'opcodes sont échangés car pour le processeur
ARM les intructions sont encodées comme ceci:
dernier octet en premier et ensuite le premier (pour les modes Thumb et Thumb-2)
ou pour les intructions en mode ARM le quatrième octet vient en premier, ensuite
le troisième, puis le second et enfin le premier (à cause des différents \gls{endianness}).

C'est ainsi que les octets se trouvent dans le listing d'IDA:
\begin{itemize}
\item pour les modes ARM et ARM64: 4-3-2-1;
\item pour le mode Thumb: 2-1;
\item pour les paires d'instructions 16-bit en mode Thumb-2: 2-1-4-3.
\end{itemize}

\myindex{ARM!\Instructions!MOVW}
\myindex{ARM!\Instructions!MOVT.W}
\myindex{ARM!\Instructions!BLX}

Donc, comme on peut le voir, les instructions \TT{MOVW}, \TT{MOVT.W} et \TT{BLX}
commencent par \TT{0xFx}.

Une des instructions Thumb-2 est \TT{MOVW R0, \#0x13D8} ~---elle stocke une valeur
16-bit dans la partie inférieure du registre \Reg{0}, éffaçant les bits supérieurs.

Aussi, \TT{MOVT.W R0, \#0} ~fonctionne comme \TT{MOVT} de l'exemple précédent
mais il fonctionne en Thumb-2.

\myindex{ARM!mode switching}
\myindex{ARM!\Instructions!BLX}

Parmi les autres différences, l'instruction \TT{BLX} est utilisée dans ce cas à
à la place de \TT{BL}.

La différence est que, en plus de sauver \ac{RA} dans le registre \ac{LR} et de
passer le contrôle à la fonction \puts, le processeur change du mode Thumb/Thumb-2
au mode ARM (ou inversement).

Cette instruction est placée ici, car l'instruction à laquelle est passée le contrôle
ressemble à (c'est encodé en mode ARM):

\begin{lstlisting}[style=customasmARM]
__symbolstub1:00003FEC _puts           ; CODE XREF: _hello_world+E
__symbolstub1:00003FEC 44 F0 9F E5     LDR  PC, =__imp__puts
\end{lstlisting}

Il s'agit principalement d'un saut à l'endroit où l'adresse de \puts est écrit
dans la section import.

Mais alors, le lecteur attentif pourrait demander: pourquoi ne pas appeler \puts
depuis l'endroit dans le code où on en a besoin ?

Parce que ce n'est pas très éfficace en terme d'espace.

\myindex{Dynamically loaded libraries}
Presque tous les programmes utilisent des bibliothèques dynamiques externes
(comme les DELL sous Windows, les .so sous *NIX ou les .dylib sous \MacOSX).
Les bibliothèques dynamiques contiennent les bibliothèques fréquemment utilisées,
incluant la fonction C standard \puts.

\myindex{Relocation}
Dans un fichier binaire exécutable (Windows PE .exe, ELF ou Mach-O) se trouve
une section d'import.
Il s'agit d'une liste des symboles (fonctions ou variables globales) importées
depuis des modules externes avec le nom des modules eux-même.

Le chargeur de l'\ac{OS} charge tous les modules dont il a besoin, tout en énumérant
les symboles d'import dans le module primaire, il détermine l'adresse correcte de
chaque symbole.

Dans notre cas, \IT{\_\_imp\_\_puts} est une variable 32-bit utilisée par le
chargeur de l'\ac{OS} pour sauver l'adresse correcte d'une fonction dans une
bibliothèque externe.
Ensuite l'instruction \TT{LDR} lit la valeur 32-bit depuis cette variable et
l'écrit dans le registre \ac{PC}, lui passant le contrôle.

Donc, pour réduire le temps dont le chargeur de l'\ac{OS} à besoin pour réaliser
cette procédure, c'est une bonne idée d'écrire l'adresse de chaque symbole une
seule fois, à une place dédiée.

\myindex{thunk-functions}

A côté de ça, comme nous l'avons déjà compris, il est impossible de charger
une valeur 32-bit dans un registre en utilisant seulement une instruction
sans un accès mémoire.

Donc, la solution optimale est d'allouer une fonction séparée fonctionnant en
mode ARM avec le seul but de passer le contrôle à l bibliothèque dynamique et
ensuite de sauter à cette petite fonction d'une instruction (ainsi appelée
\glslink{thunk function}{fonction thunk}) depuis le code Thumb.

\myindex{ARM!\Instructions!BL}
A propos, dans l'exemple précédent (compilé en mode ARM), le contrôle est
passé par \TT{BL} à la même \glslink{thunk function}{fonction thunk}.
Le mode du processeur, toutefois, n'est pas échangé (d'où l'absence d'un \q{X}
dans le mnémonique de l'instruction).

\myparagraph{Plus à propos des fonctions thunk}
\myindex{thunk-functions}

Les fonctions thunk sont difficile à comprendre, apparement, à cause d'un
mauvais nom.
La manière la plus simple est de les voir comme des adaptateurs ou des
convertisseurs d'un type jack à un autre.
Par exemple, un adaptateur permettant l'insertion d'un cordon électrique
britannique sur une prise murale américaine, ou vice-versa.
Les fonctions thunk sont parfois appelées \IT{wrappers}.

Voici quelques autres descriptions de ces fonctions:

\begin{framed}
\begin{quotation}
“Un morceau de code qui fournit une adresse:”, d'après P. Z. Ingerman, qui inventa
thunk en 1961 comme un moyen de lier les paramètres réels à leur définition
formelle dans les appels de procédures en Algol-60. Si une procédure est appelée
avec une expression à la place d'un paramètre formel, le compilateur génère un
thunk qui calcule l'expression et laisse l'adresse du résultat dans une place
standard.

\dots

Microsoft et IBM ont tous les deux défini, dans systèmes basés sur Intel, un
"environnement 16-bit" (avec leurs horribles registres de segment et la limite des
adresses à 64K) et un "environnement 32-bit" (avec un adressage linéaire et une
gestion semi-réelle de la mémoire). Les deux environnements peuvent fonctionner
sur le même ordinateur et OS (grâce à ce qui est appelé, dans le monde
Microsoft, WOW qui signifie Windows dans Windows). MS et IBM ont tous deux décidé
que le procédé de passer de 16-bit à 32-bit et vice-versa est appelé un "thunk";
pour Window 95, il y a même un outil, THUNK.EXE, appelé un "compilateur thunk".
\end{quotation}
\end{framed}
% TODO FIXME move to bibliography and quote properly above the quote
( \href{http://go.yurichev.com/17362}{The Jargon File} )

\myindex{LAPACK}
\myindex{FORTRAN}
Nous pouvons trouver un autre exemple dans la bibliothèque LAPCAK---un ``Linear Algebra PACKage''
écrit en FORTRAN.
Les développeurs \CCpp veulent aussi utiliser LAPACK, mais c'est un non-sens de
la récrire en \CCpp et de maintenir plusieurs versions.
Donc, il y a des petites fonctions que l'on peut invoquer depuis un environnement
\CCpp, qui font, à leur tour, des appels aux fonctions FORTRAN, et qui font
presque tout le reste:

\begin{lstlisting}[style=customc]
double Blas_Dot_Prod(const LaVectorDouble &dx, const LaVectorDouble &dy)
{
    assert(dx.size()==dy.size());
    integer n = dx.size();
    integer incx = dx.inc(), incy = dy.inc();

    return F77NAME(ddot)(&n, &dx(0), &incx, &dy(0), &incy);
}
\end{lstlisting}

Donc, ce genre de fonctions est appelé ``wrappers''.

